package com.example.demo1.controller;

import com.example.demo1.annotation.Log;
import com.example.demo1.objects.QueryParams0;
import com.example.demo1.objects.ReturnObject0;
import com.example.demo1.objects.ReturnObject1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@RestController
public class TesterController {
    private static final Logger log = LoggerFactory.getLogger(TesterController.class);

    @Autowired
    ReturnObject0 roX;

    @Autowired
    @Qualifier("returnObject1") //必须加上它，否则Spring 无法分清楚注入的bean 是returnObject1 还是childReturnObject1
    ReturnObject1 roY;

    @Resource(name="childReturnObject1") //另一种java 注入方法，一般用上面的Spring 注入方法@Autowired
    ReturnObject1 roY2;

    //运行此程序成功后，请在浏览器输入http://localhost:8082/hello?a=11&b=22，然后观察IDEA Console 输出是否存在
    //c.e.demo1.controller.TesterController    : a: 11, b:22
    @PreAuthorize("@ss.equals('NG')")
    @GetMapping("/hello")
    public String hello(String a, int b) {
        log.info("a: " + a + ", b:" + b);
        return "hello";
    }

    //知识点: 1. get 操作处理 2. get URL 参数映射 3. get 返回值
    //操作：浏览器地址访问URL：http://localhost:8082/ro0?a=11&b=22
    //预期结果：
    //  前端：显示{"a0":null}
    //  后端：IDEA Console 输出c.e.demo1.controller.TesterController    : a: 11, b:22
    @GetMapping("/ro0")
    public ReturnObject0 ro0(String a, int b) {
        log.info("a: " + a + ", b:" + b);
        ReturnObject0 ro0 = new ReturnObject0();
        return ro0;
    }

    //知识点: 1. get URL 参数映射为类
    //操作：浏览器地址访URL：http://localhost:8082/qp0?a=11&b=22，
    //预期结果：
    //  前端：显示{"a0":null}
    //  后端：IDEA Console 输出c.e.demo1.controller.TesterController    : qp0.a: 11, qp0.b:22
    @GetMapping("/qp0")
    public ReturnObject0 qp0(QueryParams0 qp0) {
        log.info("qp0.a: " + qp0.getA() + ", qp0.b:" + qp0.getB());
        ReturnObject0 ro0 = new ReturnObject0();
        return ro0;
    }

    //知识点: 1. 返回依赖注入[变量的初始化由Spring 框架完成，再注入到此类成员变量]过的成员变量。
    //操作：浏览器地址访URL：http://localhost:8082/qp1?a=11&b=22，
    //预期结果：
    //  前端：显示{"a0":"123456"}。其中123456 为@Value 注解的值
    //  后端：IDEA Console 输出c.e.demo1.controller.TesterController    : qp0.a: 11, qp0.b:22
    @GetMapping("/qp1")
    public ReturnObject0 qp1(QueryParams0 qp0) {
        log.info("qp0.a: " + qp0.getA() + ", qp0.b:" + qp0.getB());
        return roX;
    }

    @Log(name="Annotation.Aspect")
    //注意！！！：不推荐按此方式定义ReturnObject1 的getXXX 函数和public 成员变量
    //知识点: 1. 返回给前端的json 字段组成，取决于ReturnObject1 内部定义getXXX 函数和public 成员变量个数
    //操作：浏览器地址访URL：http://localhost:8082/qp2?a=11&b=22，
    //预期结果：
    //  前端：显示{"aa":1000,"axx":100}
    //  后端：IDEA Console 输出c.e.demo1.controller.TesterController    : qp0.a: 11, qp0.b:22
    @GetMapping("/qp2")
    public ReturnObject1 qp2(QueryParams0 qp0) {
        log.info("qp0.a: " + qp0.getA() + ", qp0.b:" + qp0.getB());
        return roY;
    }

    @Log(name="Annotation.Aspect1")
    // 同qp2，因为ChildReturnObject1 里没有public getXXX 函数或者成员变量，所以c 不会到json 里返回给前端
    @GetMapping("/qp3")
    public ReturnObject1 qp3(QueryParams0 qp0) {
        log.info("qp0.a: " + qp0.getA() + ", qp0.b:" + qp0.getB());
        return roY2;
    }
}
